#!/usr/bin/perl

use Data::Dumper;

my @m = ();
my $m = {};
my %o = ();
my $io = {};

while (<>) {
	my ($c, @a) = split;
	if ("module" eq $c) {
		flush_module();
		@m = @a;
	} elsif ("fixed" eq $c or "variable" eq $c) {
		flush_io();
		$iok = $c;
	} elsif ("input" eq $c or "output" eq $c) {
		$io->{$c} = [@a];
	} elsif ("required" eq $c or "optional" eq $c) {
		$m->{$c} = [] unless $m->{$c};
		push @{ $m->{$c} }, "@a"; 
	} elsif ("options" eq $c) {
		$m->{$c} = {} unless $m->{$c};
		my $k = shift @a;
		$m->{$c}{$k} = [@a];
	}
}
flush_module();

print "modules = {\n";
print join ",\n",
map {js_module($_)} 
sort keys %o;
print "\n};\n";

sub js_module {
	my $k = shift;
	my @a = (
		qq(name: "$k"),
		js_io($k),
		js_options($k),
		js_init($k),
	);
	return "\n$k: {\n\t" . (join ",\n", @a) . "\n}";
}

sub js_init {
	my $k = shift;
	map {qq(\t$_: [\n).(
		join ",\n",
		map {qq(\t\t"$_")}
		@{ $o{$k}{$_} }
	).qq(\n\t])}
	grep {$o{$k}{$_}}
	qw(required optional);
}

sub js_options {
	my $k = shift;
	return
	map {qq(\t$_: {\n).(
		join ",",
		map {qq(\t\t$_: [).(
			join ",",
			map {qq("$_")}
			@{ $o{$k}{'options'}{$_} }
		).qq(])}
		keys %{ $o{$k}{$_} }
	).qq(\n\t})}
	grep {$o{$k}{$_}}
	qw(options);
}

sub js_io {
	my $k = shift;
	return
	map {js_iot($k, $_)}
	grep { $o{$k}{$_} }
	qw(fixed variable);
}

sub js_iot {
	my $k = shift;
	my $t = shift;
	my $o = 
	join ",\n",
	map {js_iov($k, $t, $_)}
	grep { $o{$k}{$t}{$_} }
	qw(input output);
	return qq(\t$t: {\n$o\n\t});
}

sub js_iov {
	my $k = shift;
	my $t = shift;
	my $v = shift;
	my $o = 
	join ',',
	map {qq("$_")}
	@{ $o{$k}{$t}{$v} };
	return qq(\t\t$v: [$o]);
}

sub flush_module {
	flush_io();
	$o{$_} = $m for @m;
	$m = {};
}

sub flush_io {
	$m->{$iok} = $io if $iok;
	$iok = '';
	$io = {};
}
